/**
 * @file    Expression classname is undefined on line 2, column 15 in Templates/Classes/Class.java.
 * @author  Haseeb Yousaf
 * @see     LICENSE (MIT style license file)
 * @version 1.0
 * @date    Nov 13, 2011 2:37:26 PM
 */
package carrello.model.persist;
import java.util.Map;
import java.util.HashMap;
import java.io.Serializable;

import org.hibernate.Query;
import org.hibernate.Criteria;


public interface IEntityManager {
    /**
     * Signals the beginning of what could be considered a 'unit of work' for
     * this {@link IEntityManager}, eg: for a database-backed IEntityManager, this
     * method would start a JDBC transaction.
     */
    public void beginUnitOfWork();
    
    /**
     * Signals the end of what could be considered a 'unit of work' for this
     * {@link IEntityManager}, eg: for a database-backed IEntityManager, this
     * method would attempt to commit a JDBC transaction.
     */
    public void endUnitOfWork();
    
    /**
     * Signals the beginning of what could be considered a 'unit of work' for
     * this {@link IEntityManager}, eg: for a database-backed IEntityManager, this
     * method would abort (rollback) a JDBC transaction.
     */
    public void abortUnitOfWork();
    
    /** Count all objects of the given class in the current data store. */
    public <T> int countAll(Class<T> c);
    
    /**
     * Create a new entity object of the given class.
     * 
     * @param <T>
     *            Class of clazz
     * @param clazz
     *            Class to create an entity object for
     * @return New instance of the object
     */
    public <T> T createNew(Class<T> c);
    
    /**
     * Returns a {@link Criteria} object, based on the given {@link Class},
     * which can be used to perform adhoc queries against the data store
     * represented by this {@link IEntityManager}.
     */
    public <T> Criteria createQuery(Class<T> c);
    
    /**
     * Returns a {@link Query} object that corresponds to an existing query with
     * the given string name, which can be used to execute pre-prepared queries
     * against the data store represented by this {@link IEntityManager}.
     * 
     * @param name_of_query
     *            The name of the query - note that query names are generally
     *            prefixed by the fully-qualified class name of the object type
     *            they return.
     * @return an instance of a Query object that can perform the given named
     *         query.
     */
    public Query getQuery(String name_of_query) throws Exception;
    
    /**
     * Look up and return the entity object with the given objectId for the
     * given class/type, returning null if no such object exists in the current
     * data store.
     * 
     * @param <T>
     *            Class of entity to return
     * @param clazz
     *            Class to create an entity object for
     * @param entityId
     *            Id of entity to try populating data from
     * @return Entity object with the given objectId, null otherwise
     */
    public <T> T lookup(Class<T> c, int entity_id) throws Exception;
            
    /**
     * Store an entity in the data store that this IEntityManager represents
     * 
     * @param <T>
     *            Class of entity
     * @param entity
     *            Entity to store
     */
    public <T> void store(T entity);
    
    /**
     * Remove an entity from the data store that this IEntityManager represents
     * 
     * @param <T>
     *            Class of entity
     * @param entity
     *            Entity to store
     */
    public <T> void remove(T entity);
    
    /**
     * Update an entity in the data store that this IEntityManager represents
     * 
     * @param <T>
     *            Class of entity
     * @param entity
     *            Entity to store
     */
    public <T> void update(T entity);
    
    public <T> void revert(T entity);
    
    /**
     * Force (flush) the current set of changes to the data store. This is
     * normally done as needed by the data store itself, however it is
     * occasionally necessary to force this behaviour, for example, if the data
     * store-generated ID for a new object is needed immediately for subsequent
     * operations.
     */
    public void flush();
    
}